/*
 * RarHandler.java
 *
 * Created on 02 January 2010, 8:19
 */

package fasea.index.filehandler;

import de.innosystec.unrar.Archive;
import de.innosystec.unrar.exception.RarException;
import de.innosystec.unrar.rarfile.FileHeader;
import fasea.utils.FileUtil;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;

/**
 *
 * @author gvasil
 */
class RARHandler extends FileHandler {
    
  public Document getTypedDocument(File file) throws FileHandlerException {
      Archive ar = null;
      
      try {
          ar = new Archive(file);
      } catch (RarException ex) {
          throw new FileHandlerException(ex.getMessage());
      } catch (IOException ex) {
          throw new FileHandlerException(ex.getMessage());
      }

      if (ar.isEncrypted() == true) {
          throw new FileHandlerException("Archive is encrypted.");
      }

      org.apache.lucene.document.Document doc = createDefaultLuceneDocument(file);
      
      String text = null;
      try {
          text = getText(ar);
      }
      catch(IOException e) {
          throw new FileHandlerException("Cannot read the zip document", e);
      }
      
      if (text != null && text.trim().length() > 0) {
          doc.add(new Field("content", text, Field.Store.NO,
                  Field.Index.ANALYZED, Field.TermVector.WITH_OFFSETS));
      }

      return doc;
  }
  
  private String getText(Archive archive) throws IOException {
      File tmpDir = FileUtil.createTempDir();
      String tmpDirPath = tmpDir.getPath();

      List<FileHeader> fileList = archive.getFileHeaders();

      /* build directory tree */
      /* XXX TODO fix this */
      Iterator i = fileList.iterator();
      while (i.hasNext()) {
          FileHeader fhd = (FileHeader) i.next();

          if (fhd.isDirectory()) {
              String outFileName = tmpDirPath + File.separator + fhd.getFileNameString();
              File dir = new File(outFileName);
              dir.mkdirs();
          }
      }

      StringBuilder str = new StringBuilder();

      i = fileList.iterator();
      while (i.hasNext()) {
          FileHeader fhd = (FileHeader) i.next();

          if (fhd.isDirectory()) {
              continue;
          }

          String outFileName = null;

          // unrar archive
          outFileName = tmpDirPath + File.separator + fhd.getFileNameString();
          OutputStream out = new FileOutputStream(outFileName);
          try {
              archive.extractFile(fhd, out);
          } catch (RarException ex) {
              throw new IOException(ex.getMessage());
          }
          out.close();

          try {
              LuceneDocumentFactory handler = new LuceneDocumentFactory(false); //store text, not thumbs
              Document doc = handler.getDocument(new File(outFileName));
              if (doc != null) {
                  String content = doc.get("content");
                  if(content != null && !content.isEmpty()){
                    str.append(content).append("\n");
                  }
              }
          } catch (Exception ex) {
              //do nothing...
          }
          
      }

      // delete unrar'ed files
      FileUtil.deleteDir(tmpDir);

      return str.toString();

  }
}